<!--
 * @Author: Liu jm (cdtye)
 * @Date: 2019-11-01 10:45:31
 * @LastEditTime: 2021-07-16 14:21:15
 * @LastEditors: Liu Zhiwang
 * @FilePath: \itps-main\src\views\home\charts\health-gis.vue
 * @Description: 矢量示意图显示线路、区站
 -->
<template>
  <app-mapview basemap="SIM" @mapview-loaded="mapviewLoaded" />
</template>
<script>
import { getLineData } from './health-gis/line.js'
import { getSiteData } from './health-gis/site.js'
import appMapview from '@/components/ItpsMap/AppMapview'

// import {
//   Vector as VectorLayer
// } from 'ol/layer'
// import { Vector as VectorSource } from 'ol/source'
// import { Point, MultiLineString } from 'ol/geom'
// import Feature from 'ol/Feature'
// import { Style, Fill, Stroke, Circle, Text } from 'ol/style'

export default {
  components: { appMapview },

  data() {
    return {
      // view: null
      mapOBJ: null,
      labelZone: {
        // 标注偏移分区
        topLeft: [
          '坪石',
          '黄岗',
          '高桥',
          '冬瓜铺',
          '英德西',
          '清远',
          '银盏坳',
          '广州北',
          '古市',
          '鼎湖山',
          '肇庆西',
          '碧江',
          '江门东',
          '小榄',
          '古镇',
          '开平南',
          '阳东',
          '明珠',
          '广宁'
        ],
        topRight: [
          '罗家渡',
          '乐昌东',
          '梅村',
          '珠玑巷',
          '军田',
          '马坝',
          '乌石',
          '河头',
          '中山北',
          '潖江口',
          '源潭',
          '广州北（广坪）',
          '江高镇',
          '肇庆东',
          '广州南',
          '顺德',
          '容桂',
          '南朗',
          '庆盛',
          '虎门',
          '光明城'
        ],
        bottomLeft: [
          '土岭',
          '张滩',
          '安口',
          '韶关',
          '顺德学院',
          '云浮东',
          '南江口',
          '北滘',
          '前山',
          '阳江',
          '郭塘'
        ],
        bottomRight: [
          '南雄',
          '大坑口',
          '连江口',
          '棠溪',
          '端州',
          '礼乐',
          '珠海',
          '深圳北',
          '唐家湾'
        ],
        top: ['总甫', '乐昌', '佛山西', '丹霞山', '中山'],
        bottom: [
          '三水南',
          '肇庆',
          '恩平',
          '台山',
          '始兴',
          '马市',
          '腊石坝',
          '江门',
          '东升'
        ],
        left: ['新会', '双水镇', '翠亨', '怀集', '郁南'],
        right: ['沙口', '英德', '长坝', '南头', '珠海北']
      },
      labelLevel: {
        // 标注显示层级设定
        l4: [
          '坪石',
          '珠玑巷',
          '广州南',
          '怀集',
          '郁南',
          '阳江',
          '珠海',
          '深圳北'
        ],
        l5: ['韶关', '英德', '肇庆', '江门'],
        l6: [
          '始兴',
          '乐昌',
          '沙口',
          '清远',
          '虎门',
          '中山',
          '南江口',
          '佛山西',
          '广州北',
          '恩平'
        ],
        l7: [
          '黄岗',
          '丹霞山',
          '马坝',
          '英德西',
          '连江口',
          '肇庆东',
          '广宁',
          '光明城',
          '珠海北',
          '顺德学院',
          '台山',
          '江高镇'
        ]
      }
    }
  },
  methods: {
    mapviewLoaded(paramters) {
      this.mapOBJ = paramters.mapOBJ

      // 线路、站场、触发父组件钩子
      new Promise((resolve, reject) => {
        resolve(this.addLine(this.mapOBJ))
      })
        .then(mapOBJ => {
          return this.addSite(mapOBJ)
        })
        .then(mapOBJ => {
          this.$emit('mapLoaded', { mapOBJ: this.mapOBJ })
        }).catch(err => {
          this.$emit('mapLoaded', { mapOBJ: this.mapOBJ })
          console.log('地图加载失败：', err)
        })
    },
    addLine: function(mapOBJ) {
      return new Promise((resolve, reject) => {
        const lineData = getLineData()

        resolve(lineData)
      }).then(result => {
        const featureArr = []

        // 构造多段线（数组）
        result.data.features.forEach(feature => {
          // eslint-disable-next-line no-undef
          const lineGeom = new MultiLineString(feature.geometry.paths)
          const feaOpts = Object.assign(
            { geometry: lineGeom },
            feature.properties
          )
          // eslint-disable-next-line no-undef
          const lineFea = new Feature(feaOpts)

          featureArr.push(lineFea)
        })

        // eslint-disable-next-line no-undef
        const lineSource = new VectorSource({

          features: featureArr

        })

        // eslint-disable-next-line no-undef
        const lineLayer = new VectorLayer({

          source: lineSource,

          // eslint-disable-next-line no-undef
          style: new Style({
            // eslint-disable-next-line no-undef
            stroke: new Stroke({
              color: 'green',
              width: 2
            })
          })

        })

        mapOBJ.addLayer(lineLayer)

        return mapOBJ
      })
    },
    addSite: function(mapOBJ) {
      // const _this = this

      return new Promise((resolve, reject) => {
        // 异步获得站场数据
        const siteData = getSiteData()

        resolve(siteData)
      }).then(result => {
        const featureArr = []
        const siteLineArr = []

        // 构造Feature
        result.data.features.forEach((feature, feaIndex) => {
          if (feature.geometry.paths) {
            // 区间站场
            // eslint-disable-next-line no-undef
            const lineGeom = new MultiLineString(feature.geometry.paths)
            const feaOpts = Object.assign(
              { geometry: lineGeom },
              feature.properties
            )
            // eslint-disable-next-line no-undef
            const lineFea = new Feature(feaOpts)
            siteLineArr.push(lineFea)
          } else {
            // 点站场
            // eslint-disable-next-line no-undef
            const pointGeom = new Point([
              feature.geometry.x,
              feature.geometry.y
            ])
            const feaOpts = Object.assign(
              { geometry: pointGeom },
              feature.properties
            )
            // eslint-disable-next-line no-undef
            const lineFea = new Feature(feaOpts)
            featureArr.push(lineFea)
          }
        })

        // eslint-disable-next-line no-undef
        const pointSource = new VectorSource({
          features: featureArr.concat(siteLineArr)
        })

        // eslint-disable-next-line no-undef
        const pointLayer = new VectorLayer({
          source: pointSource,
          style: this.siteStyleFunction
        })

        mapOBJ.addLayer(pointLayer)
        return mapOBJ
      })
    },
    // 区间站场样式方法回调
    siteStyleFunction(feature) {
      var result = []

      // 点状区间站场
      // eslint-disable-next-line no-undef
      if (feature.getGeometry() instanceof Point) {
        this.siteStyleFuncPoint(feature, result)
      } else {
        // 线状区间站场
        this.siteStyleFuncLine(feature, result)
      }
      return result
    },
    // 点状区间站场
    siteStyleFuncPoint(feature, arr) {
      // 区站名称
      const siteName = feature.get('siteName')

      // 检查view
      if (!this.mapOBJ.getView()) {
        console.log('view不存在！')
        return null
      }

      // 当前层级，可能有小数
      let curZoomLevel = parseInt(this.mapOBJ.getView().getZoom())
      curZoomLevel = curZoomLevel <= 4 ? 4 : curZoomLevel // 小于4的层级，归一至4
      // 等级表
      const levelTab = this.labelLevel

      // 检查4次，如果不在对应组内，则返回null，不渲染
      const levelArr = [4, 5, 6, 7]
      for (let i = 0; i < levelArr.length; i++) {
        let arr = []
        for (let j = 4; j <= levelArr[i]; j++) {
          arr = arr.concat(levelTab['l' + j])
        }
        if (curZoomLevel <= levelArr[i] && arr.indexOf(siteName) < 0) { return null }
      }

      // 获得偏移量
      const offset = this.getSiteTextOffset(feature.get('siteName'))
      // eslint-disable-next-line no-undef
      const pointStyle = new Style({
        // eslint-disable-next-line no-undef
        image: new Circle({
          // eslint-disable-next-line no-undef
          fill: new Fill({
            color: 'white'
          }),
          // eslint-disable-next-line no-undef
          stroke: new Stroke({
            color: 'black',
            width: 1
          }),
          radius: 4
        }),
        text: new Text({
          text: siteName,
          offsetX: offset[0],
          offsetY: offset[1],
          font: 'bold 11px Times New Roman',
          // eslint-disable-next-line no-undef
          fill: new Fill({
            color: '#000'
          }),
          // eslint-disable-next-line no-undef
          stroke: new Stroke({
            color: 'white',
            width: 1
          })
        })
      })
      arr.push(pointStyle)
    },
    // 线状区间站场
    siteStyleFuncLine(feature, arr) {
      // eslint-disable-next-line no-undef
      const siteLineStyle = new Style({
        // eslint-disable-next-line no-undef
        stroke: new Stroke({
          color: 'green',
          width: 2
        })
      })

      arr.push(siteLineStyle)
    },
    // 计算站场名称偏移量
    getSiteTextOffset(siteName) {
      var stepPixel = 8 // 偏移步长
      var ratio = siteName.length / 2 // 偏移比例

      // 八向
      var directionArr = [
        'topLeft',
        'topRight',
        'bottomLeft',
        'bottomRight',
        'top',
        'bottom',
        'left',
        'right'
      ]

      // 偏移系数数组
      var offsetRatioArr = [
        [-2, -1],
        [2, -1],
        [-2, 1],
        [2, 1],
        [0, -1.5],
        [0, 1.5],
        [-2.3, 0],
        [2.3, 0]
      ]

      for (let i = 0; i < directionArr.length; i++) {
        if (this.labelZone[directionArr[i]].indexOf(siteName) > -1) { // 如果找到，直接返回结果
          return [offsetRatioArr[i][0] * stepPixel * ratio,
            offsetRatioArr[i][1] * stepPixel
          ]
        }
      }

      // 如果在八向中找不到，则默认向右偏移
      return [12 * ratio, 0]
    }
  }
}
</script>
<style>
#viewDiv {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}
</style>
